//
// Created by PC on 2023/4/28.
/*
http://www.aisichuang.net/#/main/Competition/TitlePage?id=1594&raceId=1304&stateanswer=false
 2023春季伴学挑战赛06：C++语言
    时间限制: 1000 MS 内存限制: 256 MB
6的倍数
题目描述
兔兔给你一个十进制正整数n,问你可以从n中截取多少个不同的子串(连续的若干字符),使得子串构成的数字是6的倍数。
例如：当n=1234时，有且仅有12和234这两个子串是6的倍数。
两个子串只要开始或结束位置有不同，即使内容一样也认为是不同子串，不用考虑高位0的问题，006也算合格的子串。
输入格式
单个整数：表示输入的数字n
输出格式
单个整数：表示6的倍数的子串数量。
样例 #1
样例输入 #1
1234
样例输出 #1
2
样例输入 #2
 12012
样例输出 #2
6 (12 0 12 120 012 12012)
提示
对于 20% 的数据，1≤n≤10^9
对于 50% 的数据，1≤n≤10^100
对于 70% 的数据，1≤n≤10^1000
对于 100% 的数据，1≤n≤10^10^6

 * */
// 6的倍数(包括零) 条件: 2的倍数(最后一位是0或偶数) && 3的倍数(每位相加可被三整数) 用
// 视频讲解https://app19lud1c73566.h5.xiaoeknow.com/p/course/video/v_64448ab5e4b0b0bc2bdb25af?product_id=p_64448748e4b0b0bc2bdb2418 第24分钟开始 用前缀和的方法
// 用前缀和数组计算 只正确20%
//
#include <iostream>

using namespace std;

int main()
{
    int n = 1234, count = 0, len=0;
    cin>>n;
    int t = n;
    // 求整数长度
    while (t > 0)
    {
        len++;
        t/=10;
    }
    // l[]用来存贮每一位,s[]用来存贮前缀和
    int l[len],s[len+1]={0};
//    s[len]={0};
    t = n;
    // 生成原始数组
    for (int i = len-1; i >=0; --i)
    {
        l[i]=t%10;
        t/=10;
    }
//    for (int i = 0; i < len; ++i)
//        cout<<l[i]<<' ';
//    cout<<endl;
    // 生成前缀和数组
    for (int i = 1; i < len+1; ++i)
    {
        s[i]=s[i-1]+l[i-1];
    }
//    for (int i = 1; i < len+1; ++i)
//        cout<<s[i]<<' ';
//    cout<<endl;
    // 计算每段的数字之和 看能不能被3整除??
    for (int i = 1; i < len+1; ++i)
    {
        for (int j = i; j < len+1; ++j)
        {
//            cout<<s[j]-s[i];
            if (l[j-1]%2==0 and  (s[j]-s[i-1])%3==0)
                count++;
//            printf("%d %d i:%d, j:%d\n",l[j-1],s[j]-s[i-1],i,j);
        }
    }

    cout<<count<<endl;
    return 0;
}
